package com.tanhua.server.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tanhua.commons.template.AipFaceTemplate;
import com.tanhua.commons.template.HuanXinTemplate;
import com.tanhua.commons.template.OssTemplate;
import com.tanhua.commons.template.SmsTemplate;
import com.tanhua.domain.db.*;
import com.tanhua.domain.mongo.CommonLikeUser;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.*;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author anshuai
 * @create 2021-01-26 16:27
 */
@Service
public class UserInfoService {

    @Reference
    private UserInfoApi userInfoApi;
    @Reference
    private QuestionApi questionApi;
    @Reference
    private SettingsApi settingsApi;
    @Reference
    private BlackListApi blackListApi;
    @Reference
    private UserApi userApi;
    @Reference
    private UserLikeApi userLikeApi;
    @Reference
    private FriendApi friendApi;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private AipFaceTemplate aipFaceTemplate;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private SmsTemplate smsTemplate;

    /**
     * 根据用户id回显个人信息
     *
     * @param id 用户id
     * @return
     */
    public ResponseEntity findById(Long id) {
        //查询id对应的用户信息
        UserInfo userInfo = userInfoApi.findById(id);

        //2. 把UserInfo转换成一个vo对象。注意：vo对象必须和API文档要求的数据完全一致
        UserInfoVO vo = new UserInfoVO();
        //   这个工具可以将参数一的字段拷贝到参数二对应的字段上,拷贝时，只会拷贝同名、同类型的属性值
        BeanUtils.copyProperties(userInfo, vo);
        vo.setAge(String.valueOf(userInfo.getAge()));

        return ResponseEntity.ok(vo);
    }

    /**
     * 我的-编辑个人资料-修改提交
     *
     * @param userInfo 用户信息
     * @return
     */
    public ResponseEntity updateUserInfo(UserInfo userInfo) {

        //根据token查询用户
        User user = UserHolder.getUser();

        //把user的id设置到userInfo对象
        userInfo.setId(user.getId());

        //把userInfo更新到数据库
        userInfoApi.update(userInfo);

        //4. 返回结果
        return ResponseEntity.ok(null);
    }

    /**
     * 用户资料 - 保存头像
     *
     * @param headPhoto 修改的头像
     * @return
     */
    public ResponseEntity updateAvatar(MultipartFile headPhoto) throws IOException {
        //- 根据token得到当前用户
        User user = UserHolder.getUser();

        //- 针对头像图片进行人脸检测，如果未通过则直接返回响应
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        if (!detect) {
            return ResponseEntity.status(500).body(ErrorResult.faceDetectFailed());
        }

        //- 把头像图片上传到阿里云，得到图片访问地址url
        String path = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());

        //- 把url设置到UserInfo里，更新到数据库
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setAvatar(path);

        userInfoApi.update(userInfo);

        return ResponseEntity.ok(null);
    }

    /**
     * 我的-通用设置-查询通用设置
     *
     * @return
     */
    public ResponseEntity findSettings() {
        //1.获取当前用户
        User user = UserHolder.getUser();

        //2.查询陌生人问题
        Question question = questionApi.findByUserId(user.getId());

        //3.查询通知设置
        Settings settings = settingsApi.findByUserId(user.getId());

        //4.构造返回值,用于返回前端页面需要的数据
        SettingsVO vo = new SettingsVO();
        //4.1设置陌生人问题
        if (question != null) {
            vo.setStrangerQuestion(question.getTxt());
        }

        //4.2设置手机号
        vo.setPhone(user.getMobile());

        //4.3设置喜欢、点赞、公告
        if (settings != null) {
            BeanUtils.copyProperties(settings, vo);
            // System.out.println(vo);
        } else {
            //如果用户没有设置过通知设置,则默认全部开启
            vo.setLikeNotification(true);
            vo.setPinglunNotification(true);
            vo.setGonggaoNotification(true);
        }

        return ResponseEntity.ok(vo);
    }

    /**
     * 我的-通用设置-查询黑名单列表
     *
     * @param page     当前页码
     * @param pagesize 每页几条
     * @return
     */
    public ResponseEntity findBlackList(int page, int pagesize) {

        //1.获取当前用户
        User user = UserHolder.getUser();

        //2. 分页查询当前用户的黑名单列表
        IPage<UserInfo> iPage = blackListApi.findByUserId(page, pagesize, user.getId());

        //3. 把结果转换成VO对象
        PageResult<UserInfo> result = new PageResult<>();
        result.setCounts((int) iPage.getTotal());
        result.setPage(page);
        result.setPagesize(pagesize);
        result.setPages((int) iPage.getPages());
        result.setItems(iPage.getRecords());

        return ResponseEntity.ok(result);
    }

    /**
     * 我的-通用设置-移除黑名单
     *
     * @param blackUserId 拉黑的用户id
     * @return
     */
    public ResponseEntity removeBlackList(long blackUserId) {
        //1.获取当前用户id
        Long userId = UserHolder.getUserId();

        //2.移除黑名单
        blackListApi.delete(userId, blackUserId);

        return ResponseEntity.ok(null);
    }

    /**
     * 我的-通用设置-设置陌生人问题
     *
     * @param content 陌生人问题
     * @return
     */
    public ResponseEntity updateQuestion(String content) {
        //获取当前用户
        User user = UserHolder.getUser();

        //查询当前用户陌生人设置的问题
        Question question = questionApi.findByUserId(user.getId());

        //设置陌生人问题
        if (question != null) {
            // 如果当前用户设置过陌生人问题，就修改
            question.setTxt(content);
            questionApi.update(question);
        } else {
            //如果用户没有设置过问题则新增
            question = new Question();
            question.setUserId(user.getId());
            question.setTxt(content);
            questionApi.save(question);
        }

        return ResponseEntity.ok(null);
    }

    /**
     * 我的-通用设置-保存通知设置
     *
     * @param settings 用户提交的通知设置参数
     * @return
     */
    public ResponseEntity saveSettings(Settings settings) {
        // - 使用UserHolder得到当前用户id
        Long userId = UserHolder.getUserId();

        // - 根据当前用户id，先查询当前用户的设置信息Settings
        Settings userSettings = settingsApi.findByUserId(userId);

        if (userSettings == null) {
            // - 如果没有查询到：把APP提交过来的数据，插入到数据库
            settings.setUserId(userId);
            settingsApi.save(settings);
        } else {
            // - 如果查询到了：把APP提交过来的数据，更新到数据库
            settings.setId(userSettings.getId());
            settingsApi.update(settings);
        }

        // - 返回响应结果
        return ResponseEntity.ok(null);
    }


    /**
     * 修改手机号- 1 发送短信验证码
     * @return
     */
    public ResponseEntity sendVerificationCode() {

        //1.获取当前用户
        User user = UserHolder.getUser();

        //2.向当前用户发送验证码
        // String sms = smsTemplate.sendSms(user.getMobile());
        String sms = "123456";

        //3. 把验证码真实值存储到redis，有效期5分钟
        redisTemplate.opsForValue().set("CODE_" + user.getMobile(),sms,Duration.ofMinutes(5));

        //响应结果
        return ResponseEntity.ok(null);
    }

    /**
     * 修改手机号 - 2 校验验证码
     * @param code 验证码
     * @return
     */
    public ResponseEntity checkVerificationCode(String code) {

        //1.查询当前用户
        User user = UserHolder.getUser();

        //2.校验验证码真实值
        String sms = redisTemplate.opsForValue().get("CODE_" + user.getMobile());
        boolean flag = sms != null && sms.equals(code);
        if (flag){
            //验证码正确,销毁验证码
            redisTemplate.delete("CODE_" + user.getMobile());
        }

        //构造返回值
        HashMap<String, Object> map = new HashMap<>();
        map.put("verification",flag);

        return ResponseEntity.ok(map);
    }

    /**
     * 修改手机号 - 3 保存
     * @param phone 用户输入的手机号
     * @return
     */
    public ResponseEntity savePhone(String phone) {
        //获取当前用户
        User user = UserHolder.getUser();

        //2. 更新手机号：只需要根据id更新mobile，不需要处理password字段，created/updated自动处理了
        User newUser = new User();
        newUser.setId(user.getId());
        newUser.setMobile(phone);

        //更新用户手机号(执行这种操作时通常将整个用户的数据全部其他的不改动全部赋值,只改动要改动的值)
        userApi.update(newUser);

        return ResponseEntity.ok(null);
    }

    /**
     * 我的-统计 互相喜欢、喜欢、粉丝 数量
     * @return
     */
    public ResponseEntity queryLikeCount() {
        //1. 调用API，查询互相喜欢的数量
        long queryFriendsCount = userLikeApi.queryFriendsCount(UserHolder.getUserId());
        //2. 调用API，查询喜欢的数量
        long queryLikeCount = userLikeApi.queryLikeCount(UserHolder.getUserId());
        //3. 调用API，查询粉丝的数量
        long queryFansCount = userLikeApi.queryFansCount(UserHolder.getUserId());

        //构造map返回结果
        HashMap<String, Object> result = new HashMap<>();
        result.put("eachLoveCount",queryFriendsCount);
        result.put("loveCount",queryLikeCount);
        result.put("fanCount",queryFansCount);

        return ResponseEntity.ok(result);
    }

    /**
     * 查询列表
     * @param type 查询的类型
     *             1 相互喜欢
     *             2 喜欢的
     *             3 粉丝
     *             4 访客
     * @param page 页码
     * @param pagesize 查询几条
     * @param nickname 昵称
     */
    public ResponseEntity queryLikeList(Integer type, int page, int pagesize, String nickname) {

        PageResult<CommonLikeUser> pageResult = null;
        if (type == 1){
            //分页查询 当前用户相互喜欢的列表：查询tanhua_users好友表，Friend==>本质是需要好友的id，缘分值 CommonLikeUser
            pageResult = userLikeApi.queryFriendsList(UserHolder.getUserId(), page, pagesize);
        }else if (type == 2){
            //分页查询 当前用户喜欢的 列表：查询user_like单向喜欢表，UserLike==>本质是需要对方的id，缘分值 CommonLikeUser
            pageResult = userLikeApi.queryLikeList(UserHolder.getUserId(), page, pagesize);
        }else if (type == 3){
            //分页查询 喜欢当前用户的 列表：查询user_like单向喜欢表，UserLike==>本质是需要对方的id，缘分值 CommonLikeUser
            pageResult = userLikeApi.queryFansList(UserHolder.getUserId(),page,pagesize);
        }else if (type == 4){
            //分页查询  当前用户的访客列表：查询visitors访客表，Visitor==>本质是需要访客的id，缘分值 CommonLikeUser
            pageResult = userLikeApi.findVisitorList(UserHolder.getUserId(), page, pagesize);
        }

        //转换成VO对象
        List<CommonLikeUser> commonLikeUserList = pageResult.getItems();
        List<CommonLikeUserVO> voList = new ArrayList<>();
        for (CommonLikeUser commonLikeUser : commonLikeUserList) {
            CommonLikeUserVO vo = new CommonLikeUserVO();
            //查询对方的用户详情
            UserInfo userInfo = userInfoApi.findById(commonLikeUser.getTargetUserId());
            BeanUtils.copyProperties(userInfo,vo);

            //设置缘分值
            vo.setMatchRate(commonLikeUser.getScore().intValue());
            //设置是否喜欢此用户
            vo.setAlreadyLove(false);

            voList.add(vo);
        }

        //构造返回值
        PageResult<CommonLikeUserVO> result = new PageResult<>();
        BeanUtils.copyProperties(pageResult,result);
        result.setItems(voList);

        return ResponseEntity.ok(result);
    }

    /**
     * 粉丝-喜欢。对某个粉丝点击了“喜欢”
     * @param targetUserId 粉丝id
     */
    public ResponseEntity likeFans(Long targetUserId) {
        //1. 删除单向的喜欢 targetId喜欢当前用户
        userLikeApi.delete(targetUserId,UserHolder.getUserId());

        //2. 建立双向的好友关系
        friendApi.addFriend(targetUserId,UserHolder.getUserId());

        //3. 把好友关系注册到环信。注意：好友双方都必须已经在环信注册过，否则好友关系添加失败
        // huanXinTemplate.addContactUser(UserHolder.getUserId(),targetUserId);

        return ResponseEntity.ok(null);
    }

    /**
     * 取消喜欢
     * @param targetUserId 用户id
     * @return
     */
    public ResponseEntity removeLike(Long targetUserId) {

        //1.删除单项喜欢的用户
        userLikeApi.delete(UserHolder.getUserId(),targetUserId);

        return ResponseEntity.ok(null);
    }
}
